<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Hello</title>
        <style>
            * {
                padding: 0;
                margin: 0;
            }

            body {
                width: 100%;
                height: 100vh;
                /* 背景渐变 */
            }

            .box {
                width: 100%;
                height: 100%;
                background-color: transparent;
                position: fixed;
                top: 0;
                left: 0;
            }
            .play {
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
                display: flex;
                flex-flow: column;
                justify-content: center;
                align-items: center;
            }
            video {
                display: none;
            }
            .play img {
                width: 50px;
                cursor: pointer;
                transition: all 0.2s;
                transform-origin: 50% 50%;
            }
            .play img:active {
                transform: scale(0.8);
            }
            .text {
                color: rgb(183, 70, 70);
                margin-bottom: 20px;
            }
            /* 你好 */
            .content {
                background: rgba(0, 0, 0, 0.2);
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
                border-radius: 10px;
                white-space: pre;
                box-sizing: border-box;
                overflow: auto;
                transition: all 0.3s;
                z-index: 99999;
                overflow-x: hidden;
            }
            .content::-webkit-scrollbar {
                width: 8px;
                height: 8px;
                transition: all 2s;
            }
            .content::-webkit-scrollbar-thumb {
                background: -webkit-gradient(linear, left top, left bottom, from(#ff8a00), to(#e52e71));
                background: rgb(221, 222, 224);
                border-radius: 30px;
                box-shadow: inset 2px 2px 2px hsla(0, 30%, 87%, 0.25), inset -2px -2px 2px rgba(232, 227, 227, 0.25);
            }
            .content::-webkit-scrollbar-thumb:hover {
                background: rgb(190, 199, 209);
            }
            canvas {
                position: fixed;
                width: 100%;
                height: 100%;
                background-color: transparent;
                /* z-index: 99; */
            }
            .cvs {
                display: none;
            }
            .heart_box {
                position: absolute;
                right: 150px;
                width: 500px;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            .son {
                position: absolute;
                width: 200px;
                height: 200px;
                animation: heartbeat 1s infinite;
            }
        </style>
    </head>

    <body>
        <canvas class="cvs"></canvas>
        <video src="./music.flac"></video>
        <div class="box">
            <div class="play">
                <div class="text">Click Here!</div>
                <img src="./play.png" alt="" />
            </div>
            <div class="content"></div>
            <div class="heart_box">
                <div class="son">
                    <div class="heart_bottom"></div>
                    <div class="heart_left"></div>
                    <div class="heart_right"></div>
                </div>
            </div>
        </div>
    </body>
    <!-- <script src="./star.js"></script> -->
    <script>
        const play = document.querySelector(".play");
        const video = document.querySelector("video");
        const content = document.querySelector(".content");
        const style = document.createElement("style");
        document.body.append(style);
        play.addEventListener("click", function () {
            video.play();
            this.animate(
                [
                    {
                        transform: "translate(-50%, -50%) scale(1)",
                    },
                    {
                        transform: " translate(-50%, -50%) scale(1.5)",
                        offset: 0.8,
                    },
                    {
                        transform: " translate(-50%, -50%) scale(0)",
                    },
                ],
                {
                    duration: 1000,
                    delay: 200,
                }
            ).finished.then(() => {
                this.remove();
                contentBoxShow();
            });
        });

        const contentBoxShow = () => {
            content
                .animate(
                    [
                        {
                            width: 0,
                            height: 0,
                        },
                        {
                            width: "500px",
                            height: "500px",
                            padding: "20px",
                        },
                    ],
                    {
                        duration: 1000,
                        fill: "forwards",
                    }
                )
                .finished.then(() => {
                    textPlay();
                });
        };
        let string = `/* 
哈喽！
认识到现在，还没跟你介绍过我的工作呢
我是一个前端程序员，
当你浏览一个网页时，能看到的所有东西，都是由我们完成。
就比如当前你看到的这个页面，可以给它添加一个背景色

*/
body{
    background-image: linear-gradient(
        -225deg, 
        #231557 0%,
        #43107a 29%,
        #ff1361 100%
    );
}
/* 也可以写很炫酷的特效，比如现在让背景变成星空 */
.cvs{
    display: block;
}
/* 现在你可以试试移动一下鼠标*/
/* 怎么样，是不是还挺好看的，哈哈 */
/* 这些对我们来说都很简单 */
/* 现在，画一个爱心送给你 */
.content{
    background: rgba(255, 255, 255, 0.2);
    top:270px;
    left:320px;
}

.heart_bottom {
        position: absolute;
        background-color: red;
        width: 200px;
        height: 200px;
        transform: rotate(45deg);
    }
.heart_left {
    position: absolute;
    background-color: red;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    transform: translate(-35%, -35%);
}
.heart_right {
    position: absolute;
    background-color: red;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    transform: translate(35%, -35%);
}
/* 然后再让他动起来 */
@keyframes heartbeat {
    0% {
        transform: scale(1);
    }
    20% {
        transform: scale(1.25) translateX(5%) translateY(5%);
    }
    40% {
        transform: scale(1.5) translateX(9%) translateY(10%);
    }
}

/* 至此，是不是已经对我的工作了解一二了呢 */
/* 但其实我们每天敲的代码并没有这么炫酷，而是很枯燥乏味 */
/* 世界的变化很快，
    很高兴我们能够相互认识，
    并且每天给予对方一些陪伴 
*/
/* 笔芯 ❤ */
`;
        let length = 0;
        const textPlay = () => {
            let str = string.substr(0, length);
            let t = setTimeout(() => {
                textPlay();
                length += 1;
            },50);
            if (length >= string.length) {
                clearTimeout(t);
                return;
            }
            content.innerHTML = str;
            style.innerHTML = str;
            content.scrollTop = content.scrollHeight;
        };
    </script>

    <script>
        // 注明代码 copy 自作者：山羊の前端小窝 https://www.bilibili.com/read/cv27116131/ 出处：bilibili
        // 定义星星的颜色
        const STAR_COLOR = "#fff";
        // 定义星星的大小
        const STAR_SIZE = 3;
        // 定义星星的最小缩放比例
        const STAR_MIN_SCALE = 0.2;
        // 定义溢出阈值
        const OVERFLOW_THRESHOLD = 50;
        // 定义星星的数量
        const STAR_COUNT = (window.innerWidth + window.innerHeight) / 8;
        // 获取canvas元素
        const canvas = document.querySelector("canvas");
        // 获取canvas的绘图上下文
        const context = canvas.getContext("2d");
        // 定义缩放比例
        let scale = 1; // device pixel ratio
        // 定义宽度和高度
        let width;
        let height;
        // 定义星星数组
        let stars = [];
        // 定义鼠标指针的位置
        let pointerX;
        let pointerY;
        // 定义速度对象
        let velocity = { x: 0, y: 0, tx: 0, ty: 0, z: 0.0009 };
        // 定义触摸输入标志
        let touchInput = false;
        // 生成星星
        generate();
        // 调整大小
        resize();
        // 运行动画
        step();
        // 当窗口大小改变时，重新调整大小
        window.onresize = resize;
        // 当鼠标在canvas上移动时，更新鼠标指针位置
        document.onmousemove = onMouseMove;
        // 当触摸屏在canvas上移动时，更新鼠标指针位置
        canvas.ontouchmove = onTouchMove;
        // 当触摸屏离开canvas时，更新鼠标指针位置
        canvas.ontouchend = onMouseLeave;
        // 当鼠标离开文档时，更新鼠标指针位置
        document.onmouseleave = onMouseLeave;
        // 生成星星
        function generate() {
            for (let i = 0; i < STAR_COUNT; i++) {
                stars.push({
                    x: 0,
                    y: 0,
                    z: STAR_MIN_SCALE + Math.random() * (1 - STAR_MIN_SCALE),
                });
            }
        }
        // 将星星放置到随机位置
        function placeStar(star) {
            star.x = Math.random() * width;
            star.y = Math.random() * height;
        }
        // 回收星星并重新放置到新的位置
        function recycleStar(star) {
            // 初始化方向为 'z'
            let direction = "z";
            // 获取速度的绝对值
            let vx = Math.abs(velocity.x);
            let vy = Math.abs(velocity.y);
            // 如果速度的绝对值大于1，则根据速度的大小随机确定方向
            if (vx > 1 || vy > 1) {
                let axis;
                // 如果水平速度大于垂直速度，则根据水平速度的比例随机确定水平或垂直方向
                if (vx > vy) {
                    axis = Math.random() < vx / (vx + vy) ? "h" : "v";
                } else {
                    axis = Math.random() < vy / (vx + vy) ? "v" : "h";
                }
                // 根据方向确定具体的移动方向
                if (axis === "h") {
                    direction = velocity.x > 0 ? "l" : "r";
                } else {
                    direction = velocity.y > 0 ? "t" : "b";
                }
            }
            // 随机设置星星的缩放比例
            star.z = STAR_MIN_SCALE + Math.random() * (1 - STAR_MIN_SCALE);
            // 根据方向设置星星的位置
            if (direction === "z") {
                // 如果方向为 'z'，则将星星放置在屏幕中心
                star.z = 0.1;
                star.x = Math.random() * width;
                star.y = Math.random() * height;
            } else if (direction === "l") {
                // 如果方向为 'l'，则将星星放置在屏幕左侧
                star.x = -OVERFLOW_THRESHOLD;
                star.y = height * Math.random();
            } else if (direction === "r") {
                // 如果方向为 'r'，则将星星放置在屏幕右侧
                star.x = width + OVERFLOW_THRESHOLD;
                star.y = height * Math.random();
            } else if (direction === "t") {
                // 如果方向为 't'，则将星星放置在屏幕顶部
                star.x = width * Math.random();
                star.y = -OVERFLOW_THRESHOLD;
            } else if (direction === "b") {
                // 如果方向为 'b'，则将星星放置在屏幕底部
                star.x = width * Math.random();
                star.y = height + OVERFLOW_THRESHOLD;
            }
        }
        // 调整大小
        function resize() {
            // 获取设备像素比例
            scale = window.devicePixelRatio || 1;
            // 设置画布的宽度和高度
            width = window.innerWidth * scale;
            height = window.innerHeight * scale;
            canvas.width = width;
            canvas.height = height;
            // 将所有星星重新放置到屏幕上
            stars.forEach(placeStar);
        }
        // 动画的每一帧
        function step() {
            // 清空画布
            context.clearRect(0, 0, width, height);
            // 更新星星的位置和速度
            update();
            // 绘制星星
            render();
            // 请求下一帧动画
            requestAnimationFrame(step);
        }
        // 更新星星的位置和速度
        function update() {
            // 缓动速度
            velocity.tx *= 0.96;
            velocity.ty *= 0.96;
            // 更新速度
            velocity.x += (velocity.tx - velocity.x) * 0.8;
            velocity.y += (velocity.ty - velocity.y) * 0.8;
            // 遍历所有星星
            stars.forEach((star) => {
                // 根据速度和缩放比例更新星星的位置
                star.x += velocity.x * star.z;
                star.y += velocity.y * star.z;
                // 根据速度和缩放比例更新星星的位置（使星星围绕屏幕中心旋转）
                star.x += (star.x - width / 2) * velocity.z * star.z;
                star.y += (star.y - height / 2) * velocity.z * star.z;
                // 更新星星的缩放比例
                star.z += velocity.z;
                // 如果星星超出屏幕范围，则重新放置到屏幕上
                if (
                    star.x < -OVERFLOW_THRESHOLD ||
                    star.x > width + OVERFLOW_THRESHOLD ||
                    star.y < -OVERFLOW_THRESHOLD ||
                    star.y > height + OVERFLOW_THRESHOLD
                ) {
                    recycleStar(star);
                }
            });
        }
        // 绘制星星
        function render() {
            // 遍历所有星星
            stars.forEach((star) => {
                // 设置绘制星星的样式
                context.beginPath();
                context.lineCap = "round";
                context.lineWidth = STAR_SIZE * star.z * scale;
                context.globalAlpha = 0.5 + 0.5 * Math.random();
                context.strokeStyle = STAR_COLOR;
                // 绘制星星的路径
                context.beginPath();
                context.moveTo(star.x, star.y);
                // 计算星星的尾巴坐标
                let tailX = velocity.x * 2;
                let tailY = velocity.y * 2;
                // 如果尾巴坐标的绝对值小于0.1，则设置为0.5
                if (Math.abs(tailX) < 0.1) tailX = 0.5;
                if (Math.abs(tailY) < 0.1) tailY = 0.5;
                // 绘制星星的尾巴
                context.lineTo(star.x + tailX, star.y + tailY);
                context.stroke();
            });
        }
        // 移动鼠标指针
        function movePointer(x, y) {
            // 如果之前有记录鼠标指针的位置，则计算鼠标指针的移动距离，并更新速度
            if (typeof pointerX === "number" && typeof pointerY === "number") {
                let ox = x - pointerX;
                let oy = y - pointerY;
                velocity.tx = velocity.tx + (ox / 8) * scale * (touchInput ? 1 : -1);
                velocity.ty = velocity.ty + (oy / 8) * scale * (touchInput ? 1 : -1);
            }
            // 更新鼠标指针的位置
            pointerX = x;
            pointerY = y;
        }
        // 当鼠标在canvas上移动时的事件处理函数
        function onMouseMove(event) {
            touchInput = false;
            movePointer(event.clientX, event.clientY);
        }
        // 当触摸屏在canvas上移动时的事件处理函数
        function onTouchMove(event) {
            touchInput = true;
            movePointer(event.touches[0].clientX, event.touches[0].clientY, true);
            event.preventDefault();
        }
        // 当鼠标离开canvas时的事件处理函数
        function onMouseLeave() {
            pointerX = null;
            pointerY = null;
        }
    </script>
</html>
